# -*- coding: utf8 -*-
import sqlite3
from time import mktime, time
import Import
import sys
import random
import re
import string


class Exam:
    path = Import.syspath
    current_word_pos = 0

    def __init__(self, f_parameters):
        ###################################################
        #Настройки за изпита
        ###################################################
        #тип на изпита: 0 - тест, 1 - учене, 2 - учени най-отдавна, 3 - учени най-малко пъти
        if f_parameters['EXAM_TYPE']:
            self.exam_type = f_parameters['EXAM_TYPE']
        else:
            self.exam_type = '1'

        #класификация (лексика или граматика)
        self.classification = f_parameters['CLASSIFICATION']

        #период за думите from_date_p, to_date_p
        self.from_date = ''
        if f_parameters['FROM_DATE']:
            self.from_date = f_parameters['FROM_DATE']
        else:
            self.from_date = '1900-01-01'

        self.to_date = ''
        if f_parameters['TO_DATE']:
            self.to_date = f_parameters['TO_DATE']
        else:
            self.to_date = '9999-12-31'

        #категории
        self.categories_included = []
        if f_parameters['CATEGORIES_INCLUDED']:
            self.categories_included = f_parameters['CATEGORIES_INCLUDED']

        self.categories_excluded = []
        if f_parameters['CATEGORIES_EXCLUDED']:
            self.categories_excluded = f_parameters['CATEGORIES_EXCLUDED']

        #брой успешни познавания за дума
        self.test_word_num = 0
        if self.exam_type != '0':
            if f_parameters['TEST_WORD_NUM']:
                self.test_word_num = f_parameters['TEST_WORD_NUM']
            else:
                self.test_word_num = 1

        #зареждаме думите
        self.word_count = sys.maxint
        if f_parameters['WORD_COUNT']:
            self.word_count = f_parameters['WORD_COUNT']

        ###################################################
        #Статистически данни за изпита
        ###################################################
        self.errors = 0

        #За актуализиране на данните за думите
        self.word_ids = []

        self.exam_word_count = 0
        ###################################################
        #Генериране на списъка с думите
        ###################################################

        #формираме заявката според вида на изпита и
        if f_parameters['PATH']:
            self.path = f_parameters['PATH']

        conn = sqlite3.connect(self.path + "DB/EasyLangLearn_db.db")
        c = conn.cursor()

        query = """select w.id, w.word, w.word_tanscr, w.word_trans 
                    from words w
                    where classification_id = """ + str(self.classification) + """ and
                          w.create_date between date('""" + self.from_date + """') and date('""" + self.to_date + """')"""
        if len(self.categories_included) > 0:
            query = query + """ and
                    (select count(wc.id)
                     from words_to_categories wc
                     where wc.word_id = w.id and
                           wc.category_id in (""" + (",".join(self.categories_included)) + """)) > 0
                           """

        if len(self.categories_excluded) > 0:
            query = query + """ and
                    (select count(wc.id)
                     from words_to_categories wc
                     where wc.word_id = w.id and
                           wc.category_id in (""" + (",".join(self.categories_excluded)) + """)) = 0
                           """

        if self.exam_type == 2:
            query += "order by last_exam_date"
        if self.exam_type == 3:
            query += "order by last_exam_date"

        tmp_words = []
        #print query
        c.execute(query)

        #за всяка класификация
        while True:
            row = c.fetchone()
            if row is None:
                break
            tmp_words.append(
                {'ID': row[0], 'WORD': row[1], 'TRANSCRIPTION': row[2], 'TRANSLATION': row[3],
                 'TEST_COUNT': self.test_word_num})

        self.words = []
        tmp_word_count = self.word_count
        i = 0

        if self.exam_type != 2 and self.exam_type != 3:
            while tmp_word_count > 0 and len(tmp_words) > 0:
                i = int(time()) % len(tmp_words)
                self.words.append(tmp_words[i])
                self.word_ids.append(str(tmp_words[i]['ID']))
                self.exam_word_count += 1
                del tmp_words[i]
                tmp_word_count -= 1
        else:
            print ""
            while tmp_word_count > 0 and len(tmp_words) > i:
                self.words.append(tmp_words[i])
                self.word_ids.append(str(tmp_words[i]['ID']))
                self.exam_word_count += 1
                i += 1
                tmp_word_count -= 1

        print 'WORDS: '+str(len(self.words))

    def is_valid_test(self):

        if self.exam_word_count == 0:
            return False
        else:
            return True

    def get_new_word(self, **kwargs):

        if len(self.words) == 0:
            #тестът е приключил и трябва да въведем информацията
            self.update_word_exam_info()
            test_result = self.get_exam_info()
            return {'WORD': '', 'RESULT': test_result}

        #i = random.randint(0, len(self.words) - 1)
        #current_word_pos = random.randint(0, len(self.words) - 1)
        self.current_word_pos = int(time()) % len(self.words)

        return {'WORD':self.words[self.current_word_pos]['TRANSLATION']}

    def check_word(self, **kwargs):
        word_info = self.words[self.current_word_pos]
        db_trans = re.sub(r"\s+", ' ', ' ' + word_info['WORD'] + ' ')
        user_trans = re.sub(r"\s+", ' ', ' ' + kwargs['answer'] + ' ')
        translation = ''
        if word_info['TRANSCRIPTION']:
            translation = word_info['TRANSCRIPTION'] + "\n" + word_info['WORD']
        else:
            translation = word_info['WORD']
        f = open('log.txt', 'a')

        f.write("---\n")
        if db_trans == user_trans:
            #думата е позната
            f.write("CORRECT\n")
            f.write(self.words[self.current_word_pos]['TRANSLATION'].encode('utf-8', 'ignore')+"\n")
            f.write(str(self.words[self.current_word_pos]['TEST_COUNT'])+"\n")

            self.words[self.current_word_pos]['TEST_COUNT'] -= 1

            f.write(str(self.words[self.current_word_pos]['TEST_COUNT'])+"\n")

            if self.words[self.current_word_pos]['TEST_COUNT'] <= 0:
                del self.words[self.current_word_pos]
                f.write("EXCLUDE -> LEFT: "+str(len(self.words))+"\n")
            f.close()
            return {'TRANSLATION': translation, 'RESULT': 'CORRECT', 'CORRECT': True}
        else:
            #думата не е позната
            f.write("INCORRECT\n")
            self.errors += 1
            f.close()
            return {'TRANSLATION': translation, 'RESULT': 'INCORRECT', 'CORRECT': False}


    def get_exam_info(self, **kwargs):
        conn = sqlite3.connect(self.path + "DB/EasyLangLearn_db.db")
        c = conn.cursor()

        #създаваме exam_info

        c.execute("""select trim(name) from exam_types where shif = '"""+str(self.exam_type)+"""'""")
        row = c.fetchone()
        exam_info = u"Вид тест - "+row[0]+"\n"

        if self.from_date != '1900-01-01':
            exam_info += u"От дата "+self.from_date+"\n"
        if self.to_date != '9999-12-31':
            exam_info += u"До дата "+self.from_date+"\n"

        exam_info += u"Брой думи: "+str(self.exam_word_count)+"\n"

        cat_names = []
        if len(self.categories_included) > 0:
            c.execute("""select name from categories where id in (""" + (", ".join(self.categories_included)) +
                      """) order by name""")
            while True:
                row = c.fetchone()
                if row is None:
                    break
                cat_names.append(row[0])
            if len(cat_names) > 0:
                exam_info += (u"Включени категории: "+(", ".join(cat_names))+"\n").replace("\n","").replace("\r","")

        cat_names = []
        if len(self.categories_excluded) > 0:
            c.execute("""select name from categories where id in (""" + (", ".join(self.categories_excluded)) +
                      """) order by name""")
            while True:
                row = c.fetchone()
                if row is None:
                    break
                cat_names.append(row[0])
            if len(cat_names) > 0:
                exam_info += (u"Изключени категории: "+(", ".join(cat_names))+"\n").replace("\n","").replace("\r","")

        #Изчисляваме процента
        exam_percent = 0
        if self.exam_type == '0':
            exam_percent += 100 - (100 * self.errors / self.exam_word_count)
        else:
            exam_percent += (self.test_word_num * self.exam_word_count) * 100 / (self.errors + self.test_word_num * self.exam_word_count)

        c.execute('SELECT max(id) + 1 from exam_log', {})
        row = c.fetchone()
        new_id = row[0]
        if not new_id:
            new_id = 1
        c.execute("""insert into exam_log
                            (id, classification_id, exam_date, words_count, exam_info, exam_percent)
                     values (?,?,CURRENT_TIMESTAMP,?,?,?)""", (new_id, self.classification, self.exam_word_count,
                                                                   exam_info, exam_percent))
        conn.commit()

        return {'EXAM_INFO': exam_info, 'WORD_COUNT': self.exam_word_count, 'EXAM_PERCENT': exam_percent}

    def update_word_exam_info(self, **kwargs):
        conn = sqlite3.connect(self.path + "DB/EasyLangLearn_db.db")
        c = conn.cursor()

        c.execute("""update words
                     set last_exam_date = CURRENT_TIMESTAMP,
                         exam_number = exam_number + 1
                     where id in (""" + (",".join(self.word_ids)) + """)""", ())
        conn.commit()

if __name__ == "__main__":
    f_p = {'EXAM_TYPE': 3, 'CLASSIFICATION': 3, 'FROM_DATE': '', 'TO_DATE': '',
           'CATEGORIES_INCLUDED': ('35', '23'), 'CATEGORIES_EXCLUDED': ('19', '0'), 'TEST_WORD_NUM': 2,
           'WORD_COUNT': 2000, 'PATH': ''}
    e = Exam(f_p)
    if e.is_valid_test():
        word = e.get_new_word()
        while word['WORD']:

            res = raw_input(word['WORD']+' - ')
            check_res = e.check_word(answer=res.decode('utf-8', 'ignore'))
            print check_res['RESULT']
            print check_res['TRANSLATION'].encode('utf-8', 'ignore')
            word = e.get_new_word()

        print 'END OF THE TEST!!!'
        print 'Percent: '+str(word['RESULT']['EXAM_PERCENT'])
        print 'Words: '+str(word['RESULT']['WORD_COUNT'])
        print 'Info: '+word['RESULT']['EXAM_INFO'].encode('ascii', 'ignore')
    else:
        print "INVALID EXAM - NO WORDS!"



